package com.shield.framework.security.store.redis;

import com.shield.framework.config.ShieldConstant;
import com.shield.framework.config.ShieldSecurityProperties;
import com.shield.framework.security.auth.AuthUser;
import com.shield.framework.security.token.ShieldTokenStore;
import com.shield.framework.vo.TokenVo;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.RequiredArgsConstructor;
import net.dreamlu.mica.core.utils.CharPool;
import net.dreamlu.mica.core.utils.DesensitizationUtil;
import net.dreamlu.mica.core.utils.DigestUtil;
import net.dreamlu.mica.core.utils.WebUtil;
import net.dreamlu.mica.ip2region.core.Ip2regionSearcher;
import net.dreamlu.mica.ip2region.core.IpInfo;
import net.dreamlu.mica.redis.cache.MicaRedisCache;
import org.springframework.http.HttpHeaders;

import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.time.LocalDateTime;

/**
 * @description: jwt token 存储
 * @Author Andy
 */
@RequiredArgsConstructor
public class ShieldRedisTokenStore implements ShieldTokenStore {

    private final MicaRedisCache redisCache;
    private final Ip2regionSearcher searcher;


    @Override
    public TokenVo get(String token) {
        return redisCache.get(getCacheKeyByToken(token));
    }

    /**
     * 存储 token
     *
     * @param request    HttpServletRequest
     * @param authUser   AuthUser
     * @param token      token
     * @param expireTime expireTime
     */
    @Override
    public void save(HttpServletRequest request, AuthUser authUser, String token, Duration expireTime) {
        String storePrefix = ShieldConstant.REDIS_STORE_PREFIX;
        // key md5 避免太长，aes 后特别长
        String key = DigestUtil.md5Hex(token);
        String ip = WebUtil.getIP(request);
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader(HttpHeaders.USER_AGENT));
        String browser = userAgent.getBrowser().getName();
        TokenVo tokenVo = new TokenVo();
        tokenVo.setUserName(authUser.getUsername());
        tokenVo.setNickName(authUser.getNickName());
        tokenVo.setBrowser(browser);
        tokenVo.setIp(ip);
        IpInfo ipInfo = searcher.memorySearch(ip);
        if (ipInfo != null) {
            tokenVo.setAddress(ipInfo.getAddress());
        }
        // token 摘要，前6后8，中间4位占位符
        tokenVo.setSummary(DesensitizationUtil.sensitive(token, 8, 8, CharPool.DOT, 4));
        tokenVo.setTokenKey(key);
        tokenVo.setLoginTime(LocalDateTime.now());
        String cacheKey = storePrefix + key;
        redisCache.setEx(cacheKey, tokenVo, expireTime);
    }

    private String getCacheKeyByToken(String token) {
        String storePrefix = ShieldConstant.REDIS_STORE_PREFIX;
        String key = DigestUtil.md5Hex(token);
        return storePrefix + key;
    }

}
